home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / DJGPP / CBGRX103.ZIP / contrib / libgrx / events / event.c next >
Text File  |  1993-12-06  |  8KB  |  278 lines

  1. /**
  2.  ** EVENT.C
  3.  **
  4.  **  Copyright (C) 1992, Csaba Biegl
  5.  **    820 Stirrup Dr, Nashville, TN, 37221
  6.  **    csaba@vuse.vanderbilt.edu
  7.  **
  8.  **  This file is distributed under the terms listed in the document
  9.  **  "copying.cb", available from the author at the address above.
  10.  **  A copy of "copying.cb" should accompany this file; if not, a copy
  11.  **  should be available from where this file was obtained.  This file
  12.  **  may not be distributed without a verbatim copy of "copying.cb".
  13.  **  You should also have received a copy of the GNU General Public
  14.  **  License along with this program (it is in the file "copying");
  15.  **  if not, write to the Free Software Foundation, Inc., 675 Mass Ave,
  16.  **  Cambridge, MA 02139, USA.
  17.  **
  18.  **  This program is distributed in the hope that it will be useful,
  19.  **  but WITHOUT ANY WARRANTY; without even the implied warranty of
  20.  **  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21.  **  GNU General Public License for more details.
  22.  **/
  23.  
  24. #ifdef     TOPLINEINFO
  25. #define  FOR_GO32
  26. #define  USE_AT_BIOS
  27. #endif
  28.  
  29. #ifndef  __TURBOC__
  30. #error     Don't even try to compile it with this compiler
  31. #endif
  32.  
  33. #pragma  inline
  34.  
  35. #include <stdlib.h>
  36. #include <string.h>
  37. #include <alloc.h>
  38. #include <stdio.h>
  39. #include <time.h>
  40. #include <dos.h>
  41.  
  42. #include "eventque.h"
  43.  
  44. extern int  far _ev_interss;    /* interrupt stack segment */
  45. extern int  far _ev_interds;    /* interrupt data segment */
  46. extern int  far _ev_kbintsp;    /* keyboard interrupt stack */
  47. extern int  far _ev_msintsp;    /* mouse interrupt stack */
  48. extern int  far _ev_kbinter;    /* keyboard interrupt flag */
  49.  
  50. extern void interrupt (* far _ev_oldkbint)(void);
  51.  
  52. extern void far          _ev_mouseint(void);
  53. extern void interrupt _ev_keybdint(void);
  54.  
  55. static void dummydraw(void) {}
  56.  
  57. static EventQueue *queue = NULL;
  58. static void (*mousedraw)(void) = dummydraw;
  59. static char *stack = NULL;
  60. static char *qsave = NULL;
  61.  
  62. static int  ms_xpos;
  63. static int  ms_ypos;
  64. static int  ms_xmickey;
  65. static int  ms_ymickey;
  66. static int  first_call = 1;
  67.  
  68. #ifdef FOR_GO32
  69. static int  my_master_pic;
  70. static int  my_new_pic;
  71. #ifndef  USE_AT_BIOS        /* always use AT BIOS calls for GO32 version */
  72. #define  USE_AT_BIOS
  73. #endif
  74. #endif
  75.  
  76. #define MS_ENABLE   EVENT_ENABLE(EVENT_MOUSE)
  77. #define KB_ENABLE   EVENT_ENABLE(EVENT_KEYBD)
  78.  
  79. #define KB_SSIZE    128        /* keyboard handler stack size */
  80. #define MS_SSIZE    128        /* mouse handler MINIMAL stack size */
  81.  
  82. #define IABS(x)        (((x) > 0) ? (x) : -(x))
  83.  
  84. void far _ev_mousehandler(int msk,int btn,int mx,int my)
  85. {
  86.     EventRecord *ep;
  87.     int moved = 0;
  88.     int diff;
  89.  
  90.     if((diff = mx - ms_xmickey) != 0) {
  91.         ms_xmickey += diff;
  92.         ms_xpos    += diff;
  93.         if((diff = ms_xpos / queue->evq_xspeed) != 0) {
  94.         ms_xpos %= queue->evq_xspeed;
  95.         if(IABS(diff) >= queue->evq_thresh) diff *= queue->evq_accel;
  96.         diff += queue->evq_xpos;
  97.         if(diff <= queue->evq_xmin) diff = queue->evq_xmin;
  98.         if(diff >= queue->evq_xmax) diff = queue->evq_xmax;
  99.         if(diff != queue->evq_xpos) {
  100.             queue->evq_xpos  = diff;
  101.             queue->evq_moved = moved = 1;
  102.         }
  103.         }
  104.     }
  105.     if((diff = my - ms_ymickey) != 0) {
  106.         ms_ymickey += diff;
  107.         ms_ypos    += diff;
  108.         if((diff = ms_ypos / queue->evq_yspeed) != 0) {
  109.         ms_ypos %= queue->evq_yspeed;
  110.         if(IABS(diff) >= queue->evq_thresh) diff *= queue->evq_accel;
  111.         diff += queue->evq_ypos;
  112.         if(diff <= queue->evq_ymin) diff = queue->evq_ymin;
  113.         if(diff >= queue->evq_ymax) diff = queue->evq_ymax;
  114.         if(diff != queue->evq_ypos) {
  115.             queue->evq_ypos  = diff;
  116.             queue->evq_moved = moved = 1;
  117.         }
  118.         }
  119.     }
  120.     if((msk & ~1) && (queue->evq_enable & MS_ENABLE)) {
  121.         disable();
  122.         ep = &queue->evq_events[queue->evq_wrptr];
  123.         if(++queue->evq_wrptr == queue->evq_maxsize)
  124.         queue->evq_wrptr = 0;
  125.         if(queue->evq_cursize < queue->evq_maxsize)
  126.         queue->evq_cursize++;
  127.         else if(++queue->evq_rdptr == queue->evq_maxsize)
  128.         queue->evq_rdptr = 0;
  129.         enable();
  130.         _AX = 0x200;
  131.         geninterrupt(0x16);
  132.         ep->evt_kbstat = _AL;
  133.         ep->evt_type   = EVENT_MOUSE;
  134.         ep->evt_mask   = msk;
  135.         ep->evt_button = btn;
  136.         ep->evt_xpos   = queue->evq_xpos;
  137.         ep->evt_ypos   = queue->evq_ypos;
  138.         ep->evt_time   = clock();
  139.     }
  140.     if(moved && queue->evq_drawmouse) (*mousedraw)();
  141. }
  142.  
  143. void far _ev_keybdhandler(void)
  144. {
  145.     EventRecord *ep;
  146.     int keycode,scancode;
  147.  
  148.     if(queue->evq_enable & KB_ENABLE) for( ; ; ) {
  149. #ifdef USE_AT_BIOS
  150.         _AX = 0x1100;
  151. #else
  152.         _AX = 0x100;
  153. #endif
  154.         geninterrupt(0x16);
  155.         asm jnz  charpresent;
  156.         return;
  157.       charpresent:
  158.         scancode = _AX;
  159.         keycode  = (_AL == 0) ? _AH + 0x100 :
  160. #ifdef USE_AT_BIOS
  161.         (_AL == 0xe0) ? _AH + 0x200 :
  162. #endif
  163.         _AL;
  164.         if(queue->evq_delchar) {
  165. #ifdef USE_AT_BIOS
  166.         _AX = 0x1000;
  167. #else
  168.         _AX = 0;
  169. #endif
  170.         geninterrupt(0x16);
  171.         }
  172.         disable();
  173.         ep = &queue->evq_events[queue->evq_wrptr];
  174.         if(++queue->evq_wrptr == queue->evq_maxsize)
  175.         queue->evq_wrptr = 0;
  176.         if(queue->evq_cursize < queue->evq_maxsize)
  177.         queue->evq_cursize++;
  178.         else if(++queue->evq_rdptr == queue->evq_maxsize)
  179.         queue->evq_rdptr = 0;
  180.         enable();
  181. #ifdef USE_AT_BIOS
  182.         _AX = 0x1200;
  183. #else
  184.         _AX = 0x200;
  185. #endif
  186.         geninterrupt(0x16);
  187.         ep->evt_kbstat   = _AL;
  188.         ep->evt_keycode  = keycode;
  189.         ep->evt_scancode = scancode;
  190.         ep->evt_type     = EVENT_KEYBD;
  191.         ep->evt_time     = clock();
  192.     }
  193. }
  194.  
  195. void EventQueueDeInit(void)
  196. {
  197.     if(stack != NULL) {
  198.         _AX = 0;
  199.         geninterrupt(0x33);
  200. #ifdef FOR_GO32
  201.         setvect(my_master_pic+1,_ev_oldkbint);
  202.         if(my_new_pic != my_master_pic) setvect(my_new_pic+1,_ev_oldkbint);
  203. #else
  204.         setvect(9,_ev_oldkbint);
  205. #endif
  206.         free(stack);
  207.         free(qsave);
  208.         stack = NULL;
  209.     }
  210. }
  211.  
  212. #ifdef FOR_GO32
  213. EventQueue *EventQueueInit
  214.   (int qsize,int ms_stksize,void (*msdraw)(void),int master_pic,int new_pic)
  215. #else
  216. EventQueue *EventQueueInit(int qsize,int ms_stksize,void (*msdraw)(void))
  217. #endif
  218. {
  219.     if(stack != NULL) EventQueueDeInit();
  220.     if(qsize < 20) qsize = 20;
  221.     if(ms_stksize < MS_SSIZE) ms_stksize = MS_SSIZE;
  222.     stack = malloc(KB_SSIZE + ms_stksize);
  223.     qsave = malloc(sizeof(EventQueue)+(sizeof(EventRecord)*(qsize-1))+4);
  224.     if((stack == NULL) || (qsave == NULL)) {
  225.         if(stack != NULL) { free(stack); stack = NULL; }
  226.         if(qsave != NULL) { free(qsave); qsave = NULL; }
  227.         return(NULL);
  228.     }
  229.     _ev_interds = FP_SEG(&ms_xpos);
  230.     _ev_interss = FP_SEG(stack);
  231.     _ev_kbintsp = FP_OFF(stack) + KB_SSIZE;
  232.     _ev_msintsp = FP_OFF(stack) + KB_SSIZE + ms_stksize;
  233.     _ev_kbinter = (-1);
  234.     ms_xpos = ms_xmickey = 0;
  235.     ms_ypos = ms_ymickey = 0;
  236.     queue = (EventQueue *)(((long)qsave + 3L) & ~3L);
  237.     memset(queue,0,sizeof(EventQueue));
  238.     queue->evq_maxsize   = qsize;
  239.     queue->evq_xmax         = 79;
  240.     queue->evq_ymax         = 24;
  241.     queue->evq_xspeed    = 8;
  242.     queue->evq_yspeed    = 16;
  243.     queue->evq_thresh    = 100;
  244.     queue->evq_accel     = 1;
  245.     queue->evq_delchar   = 1;
  246.     queue->evq_enable    = MS_ENABLE | KB_ENABLE;
  247.     _AX = 0;
  248.     geninterrupt(0x33);
  249.     if(_AX != 0) {
  250.         _AX = 11;
  251.         geninterrupt(0x33);
  252.         mousedraw = (msdraw != NULL) ? msdraw : dummydraw;
  253.         _ES = FP_SEG(_ev_mouseint);
  254.         _DX = FP_OFF(_ev_mouseint);
  255.         _CX = 0xff;
  256.         _AX = 0x0c;
  257.         geninterrupt(0x33);
  258.     }
  259. #ifdef FOR_GO32
  260.     _ev_oldkbint = getvect(master_pic+1);
  261.     setvect(master_pic+1,_ev_keybdint);
  262.     if(new_pic != master_pic) setvect(new_pic+1,_ev_keybdint);
  263. #else
  264.     _ev_oldkbint = getvect(9);
  265.     setvect(9,_ev_keybdint);
  266. #endif
  267.     if(first_call) {
  268. #ifdef FOR_GO32
  269.         my_master_pic = master_pic;
  270.         my_new_pic = new_pic;
  271. #endif
  272.         atexit(EventQueueDeInit);
  273.         first_call = 0;
  274.     }
  275.     return(queue);
  276. }
  277.  
  278.